#ifndef STREAM_H
#define STREAM_H 

#include "Instruction.h"
#include "Types.h"

/// @brief Read data by LBA48 & Place the data at the target address.
/// @param sector 
/// @param size 
/// @param destination 
void LoadDataFromDisk(uint32_t index, uint32_t sectorCount, uint32_t destination)
{
    // 选择驱动器
    // 0xE0 = 0b11100000
    // bit7 (0x80)： 必须为1，表示LBA模式（否则是CHS模式）。
    // bit6 (0x40)： 选择主盘（Master），为0表示主盘，为1表示从盘（Slave）。
    // bit5 (0x20)： 也为1，LBA模式下必须置1。
    // bit4~bit0： LBA地址的24~27位（高4位），这里为0。
    Outb(0x1F6, 0xE0);

    // 这4行设置LBA48模式下的高字节参数（高24位），包括高8位的扇区数和LBA地址的高字节。
    Outb(0x1F2, (uint8_t) (sectorCount >> 8));
    Outb(0x1F3, (uint8_t) (index >> 24));		// LBA参数的24~31位
    Outb(0x1F4, (uint8_t) (0));					// LBA参数的32~39位
    Outb(0x1F5, (uint8_t) (0));					// LBA参数的40~47位

    // 这4行设置LBA48模式下的低字节参数（低24位），包括低8位的扇区数和LBA地址的低字节。
    Outb(0x1F2, (uint8_t) (sectorCount));
	Outb(0x1F3, (uint8_t) (index));			    // LBA参数的0~7位
	Outb(0x1F4, (uint8_t) (index >> 8));		// LBA参数的8~15位
	Outb(0x1F5, (uint8_t) (index >> 16));		// LBA参数的16~23位

    // 发送读取信号
	Outb(0x1F7, (uint8_t) 0x24);

    // 一次性读取2个字节
    uint16_t* buffer = (uint16_t*) destination;
    while (sectorCount--)
    {
        // 等待硬盘就绪
        while ((Inb(0x1F7) & 0xC0) != 0x40)
        {
            // do nothing
        }

        // 一次读取512字节
        for (int i = 0; i < 256; i++)
        {
            // 一次性读取2个字节
            *buffer++ = Inw(0x1F0);
        }
    }
}

#endif